import '@babel/polyfill';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import gsap from 'gsap';
import * as dat from 'dat.gui';
import VertexShader from '../shader/2/vertex.glsl';
import FragmentShader from '../shader/2/fragment.glsl';

//场景
const scene = new THREE.Scene();

//相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 200);
camera.position.set(5, 3, 5);
scene.add(camera);

//渲染器
const renderer = new THREE.WebGL1Renderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);


//纹理
const texture1 = new THREE.TextureLoader().load('./particles/9.png');
const texture2 = new THREE.TextureLoader().load('./particles/10.png');
const texture3 = new THREE.TextureLoader().load('./particles/11.png');

const params = {
    count: 100000,
    size: 0.01,
    radius: 5,
    branch: 3,
    color1: 0xff6030,
    color2: 0x1b3984,
}

let geometry = null;
let shadermaterial = null;
let points = null;
const startColor = new THREE.Color(params.color1);
const endColor = new THREE.Color(params.color2);
const generateGalaxy = () => {
    geometry = new THREE.BufferGeometry();
    const positions = new Float32Array(params.count * 3);//位置
    const colors = new Float32Array(params.count * 3);//颜色
    const scales = new Float32Array(params.count);//大小
    const imgIndex = new Float32Array(params.count);//纹理
    for (let i = 0; i < params.count; i++) {
        //当前的点应该在哪一条分支的角度上(0°，120°，240°)
        const branchAngel = (i % params.branch) * ((2 * Math.PI) / params.branch);
        const current = i * 3;
        //距离圆心距离为0-5，不均匀分布（三次函数）
        const distance = Math.random() * params.radius * Math.pow(Math.random(), 3);
        //-1~1求3次方，不均匀分布//距离圆心距离越远，长宽高越大
        const randomX = Math.pow(Math.random() * 2 - 1, 3) * distance / 5;
        const randomY = Math.pow(Math.random() * 2 - 1, 3) * distance / 5;
        const randomZ = Math.pow(Math.random() * 2 - 1, 3) * distance / 5;

        //cos(branchAngel)一条直线，随距离变换即加上distance,使用着色器进行改变
        positions[current] = Math.cos(branchAngel) * distance + randomX;
        positions[current + 1] = randomY;
        positions[current + 2] = Math.sin(branchAngel) * distance + randomZ;

        //混合颜色形成渐变色
        const mixColor = startColor.clone();
        mixColor.lerp(endColor, distance / params.radius);
        colors[current] = mixColor.r;
        colors[current + 1] = mixColor.g;
        colors[current + 2] = mixColor.b;

        //控制点的大小的数组
        scales[i] = Math.random() - 0.5;

        //控制点的纹理的数组
        imgIndex[i] = i % 3;

    }
    geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
    geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3));
    geometry.setAttribute('aScale', new THREE.BufferAttribute(scales, 1));
    geometry.setAttribute('imgIndex', new THREE.BufferAttribute(imgIndex, 1));

    shadermaterial = new THREE.ShaderMaterial({
        vertexShader: VertexShader,
        fragmentShader: FragmentShader,
        transparent: true,
        //depthWrite: false,
        uniforms: {
            uTexture1: { value: texture1 },
            uTexture2: { value: texture2 },
            uTexture3: { value: texture3 },
            uTime: { value: 0 },
        }
    })
    points = new THREE.Points(geometry, shadermaterial);
    scene.add(points);
    console.log(points);
}
generateGalaxy();


//控制
const orbitControls = new OrbitControls(camera, renderer.domElement);
orbitControls.enableDamping = true;


//坐标轴
const axesHelper = new THREE.AxesHelper(5);
scene.add(axesHelper);

const clock = new THREE.Clock();
//帧动画
function animate() {
    const time = clock.getElapsedTime();
    shadermaterial.uniforms.uTime.value = time;
    orbitControls.update();
    renderer.render(scene, camera);
    requestAnimationFrame(animate);
};
animate();

//窗口调整侦听
window.addEventListener('resize', () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setPixelRatio(window.devicePixelRatio);
});



